﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using BattleFury.Lib.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace BattleFury.Lib.Controls
{
	public class Console
		: Control
	{
		private Button _button;
		private bool _isExpanding;
		private readonly List<ConsoleMessage> _messages = new List<ConsoleMessage>();

		public Color BackgroundColor { get; set; }
		public bool IsExpanded { get; set; }
		public int ExpandSpeed { get; set; }

		public List<ConsoleMessage> Messages
		{
			get { return _messages; }
		}

		public Console()
		{
			Size = new Vector2(RenderEngine.Get().Graphics.PreferredBackBufferWidth, RenderEngine.Get().Graphics.PreferredBackBufferHeight / 2);
			Position = new Vector2(0f, -Size.Y);
			BackgroundColor = Color.Black.WithOpacity(0.5f);
			IsExpanded = false;
			_isExpanding = false;
			ExpandSpeed = 16;
		}

		#region Serialization

		public override void Serialize()
		{
			throw new NotImplementedException();
		}

		public override void Deserialize(XElement element, object callingObject)
		{
			Name = element.GetString("Name");
			BackgroundColor = element.GetColor("BackgroundColor", Color.Black.WithOpacity(0.75f));
			IsExpanded = element.GetBoolean("IsExpanded", false);
			ExpandSpeed = element.GetInt("ExpandSpeed", 16);

			_button = new Button
			{
				Size = new Vector2(64f, 32f),
				Position = Position + new Vector2(RenderEngine.Get().Graphics.PreferredBackBufferWidth - 64f, Size.Y),
				Text = "\\/",
				OnClick = ToggleExpanding,
			};
		}

		#endregion

		public override void Update(GameTime gameTime)
		{
			if (_button.Skin == null) _button.Skin = Skin;
			if (_button.Font == null) _button.Font = Font;
			_button.Update(gameTime);

			var input = RenderEngine.Get().Input;
			if(input.Keyboard.IsKeyPressed(Keys.OemTilde)) ToggleExpanding();

			if (_isExpanding && !IsExpanded)
			{
				var offset = new Vector2(0f, ExpandSpeed);
				Position += offset;
				_button.Position += offset;
				if (Position.Y >= 0)
				{
					IsExpanded = true;
					_isExpanding = false;
					_button.Text = "/\\";
					if (Position.Y > 0)
					{
						Position = new Vector2(Position.X, 0f);
						_button.Position = Position + new Vector2(RenderEngine.Get().Graphics.PreferredBackBufferWidth - 64f, Size.Y);
					}
				}
			}
			if (_isExpanding && IsExpanded)
			{
				var offset = new Vector2(0f, -ExpandSpeed);
				Position += offset;
				_button.Position += offset;
				if (Position.Y <= -Size.Y)
				{
					IsExpanded = false;
					_isExpanding = false;
					_button.Text = "\\/";
					if (Position.Y < -Size.Y)
					{
						Position = new Vector2(Position.X, -Size.Y);
						_button.Position = Position + new Vector2(RenderEngine.Get().Graphics.PreferredBackBufferWidth - 64f, Size.Y);
					}
				}
			}
		}

		public override void Draw(GameTime gameTime)
		{
			var whitePixel = RenderEngine.Get().Textures["WhitePixel"];
			SpriteBatch.Draw(whitePixel, Bounds, BackgroundColor);
			_button.Draw(gameTime);

			if (Font == null) return;

			var numberOfLines = (int)(Size.Y / Font.LineSpacing);
			var lowIndex = (_messages.Count - numberOfLines < 0) ? 0 : _messages.Count - numberOfLines;

			var offset = new Vector2(0f, Size.Y - Font.LineSpacing);
			for (var i = _messages.Count - 1; i >= lowIndex; i--)
			{
				var message = _messages[i];
				SpriteBatch.DrawString(Font, message.Message, Position + offset, message.Color);
				offset -= new Vector2(0f, Font.LineSpacing);
			}
		}

		public void ToggleExpanding()
		{
			_isExpanding = !_isExpanding;
		}

		public void WriteMessage(string message, Color color)
		{
			var consoleMessage = new ConsoleMessage
			{
				Message = message,
				Color = color
			};
			_messages.Add(consoleMessage);
		}

		public void WriteMessage(string message)
		{
			WriteMessage(message, Color.White);
		}

		public void ClearMessages()
		{
			_messages.Clear();
		}
	}
}